//
// Created by liuping on 2018/10/8.
//

#pragma once

#include <ostream>

struct Vector3 {
    Vector3 () {}
    explicit Vector3 (float mx, float my = 0.0, float mz = 0.0) : x(mx), y(my), z(mz) {}

    Vector3 & operator += (const Vector3 &v3) {
        x += v3.x;
        y += v3.y;
        z += v3.z;
        return *this;
    }

    Vector3 & operator -= (const Vector3 &v3) {
        x -= v3.x;
        y -= v3.y;
        z -= v3.z;
        return *this;
    }

    Vector3 & operator *= (const Vector3 &v3) {
        Vector3 t = *this;
        x = t.y * v3.z - t.z * v3.y;
        y = t.z * v3.x - t.x * v3.z;
        z = t.x * v3.y - t.y * v3.x;
        return *this;
    }

    float x = 0.0;
    float y = 0.0;
    float z = 0.0;
};


Vector3 operator + (const Vector3 &l, const Vector3 &r) {
    Vector3 t = l;
    t += r;
    return t;
}

Vector3 operator - (const Vector3 &l, const Vector3 &r) {
    Vector3 t = l;
    t -= r;
    return t;
}

Vector3 operator * (const Vector3 &l, const Vector3 &r) {
    Vector3 t = l;
    t *= r;
    return t;
}

float DotProduct(const Vector3 &l, const Vector3 &r) {
    return l.x * r.x + l.y * r.y + l.z * r.z;
}

std::ostream & operator << (std::ostream &os, const Vector3 &v3) {
    os << "(x,y,z):("<<v3.x<< "," << v3.y<<","<<v3.z<<")";
    return os;
}
